package com.gurumades.jsonform.client;


import java.util.HashMap;
import java.util.Vector;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Widget;
import com.gurumades.jsonform.client.constants.AppMessages;
import com.gurumades.jsonform.client.forms.FieldsetWidget;
import com.gurumades.jsonform.client.forms.FormItemViewIF;
import com.gurumades.jsonform.client.forms.FormWidgetFactory;
import com.gurumades.jsonform.client.presenter.*;

public class JsonFormView extends Composite implements JsonFormPresenter.Display {
	private JSONObject displayObject;
	private HashMap<String, JSONObject> displayObects = new HashMap<String,JSONObject>(); 
	private HashMap<String, FormItemViewIF> formItems = new HashMap<String,FormItemViewIF>(); 
	private FlowPanel flexTable;
	
	Button submitButton;

	Button cancelButton;
	
	public JsonFormView() {
		displayObject = new JSONObject();
		VerticalPanel verticalPanel = new VerticalPanel();
		initWidget(verticalPanel);
		
		flexTable = new FlowPanel();
		verticalPanel.add(flexTable);
		HorizontalPanel actionPanel = new HorizontalPanel();
		verticalPanel.add(actionPanel);
		
		submitButton = new Button(FormsMessages.Util.instance().save_button());
		cancelButton = new Button(FormsMessages.Util.instance().cancel_button());
		
		actionPanel.add(submitButton);
		actionPanel.add(cancelButton);
		
		actionPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		actionPanel.setSpacing(5);
		
		flexTable.setWidth("100%");	
	}

	/**
	 * Default method to build a screen
	 * @param displayFields
	 * @param flexTable
	 */
	public void setData(JSONValue displayFieldsArray, JSONObject displayObject, String userRole){

		displayObects.clear();
		formItems.clear();
		
		if (displayFieldsArray.isArray() == null) return;
		
		flexTable.clear();
		JSONArray array = (JSONArray)displayFieldsArray;
		for (int row = 0; row<array.size(); row++){
			JSONObject jsonRow = (JSONObject) array.get(row);
			FieldsetWidget fieldset = new FieldsetWidget();
			fieldset.setTitle(getString("label", jsonRow), getString("iconURL", jsonRow));
			
			if (!getBoolean("visible", jsonRow, true)) {
				continue;
			}
			
			flexTable.add(fieldset);
			
			if (jsonRow.containsKey("items")) {
				JSONObject items = jsonRow.get("items").isObject();
				if (items != null && items.containsKey("item")) {
					if (items.get("item").isArray() != null) {
						JSONArray line = items.get("item").isArray();
						for (int i = 0; i < line.size(); i++) {
							JSONObject formItem = line.get(i).isObject();
							
							String rowID = getString("id",formItem);
							this.displayObects.put(rowID, formItem);
							
							addRow(rowID,formItem, displayObject, fieldset);
						}
					}
				}
			}
			
			fieldset.getPanel().setOpen(!getBoolean("collapsed", jsonRow));
			
			final DisclosurePanel panel = fieldset.getPanel();
			if (!getBoolean("collapsible", jsonRow)) {
				fieldset.getPanel().setAnimationEnabled(false);
				fieldset.getPanel().addCloseHandler(new CloseHandler<DisclosurePanel>() {
					
					@Override
					public void onClose(CloseEvent<DisclosurePanel> event) {
						panel.setOpen(true);
					}
				});
			}
			
			fieldset.setDescription(getString("description", jsonRow));
			
		}		
	}
	

	private void addRow(String rowID, JSONObject jsonRow, JSONObject displayObject, FieldsetWidget flexTable){
		try{
			
			if (getBoolean("visible", jsonRow)) {
				JSONValue value = displayObject.get(rowID);
				
				JSONArray lines = new JSONArray();
				
				if (value != null) {
					if (value.isArray() == null) {
						lines.set(0, value);
					}else if(value.isArray() != null){
						lines = (JSONArray)value;
					}else{
						lines.set(0, new JSONObject());
					}
				}else{
					lines.set(0, new JSONObject());
				}
				
				
				for(int i =0; i< lines.size(); i++){
					FormItemViewIF row = FormWidgetFactory.createWidget(getString("type", jsonRow));
					flexTable.addFormItem(row.asWidget());
					row.initFormItem(displayObject.get(rowID), jsonRow);
					
					JSONValue rowValue = (JSONValue) lines.get(i);
					row.setData(rowValue);
					
					formItems.put(rowID, row);
				}
				
			}
			
		} catch (Exception ex){
		}
	}
	
	@Override
	public HasClickHandlers saveButton(){
		return submitButton;
	}
	
	@Override
	public HasClickHandlers cancelButton(){
		return cancelButton;
	}
	
	@Override
	public HashMap<String, FormItemViewIF> getFormItems() {
		return formItems;
	}
	
	private String getString(String key, JSONObject o) {
		return JSONUtils.getString(key, o);
	}
	
	private boolean getBoolean(String key, JSONObject o) {
		return JSONUtils.getBoolean(key, o);
	}
	
	private boolean getBoolean(String key, JSONObject o, boolean def) {
		return JSONUtils.getBoolean(key, o, def);
	}
	
	public JSONObject getDisplayObject() {
		return displayObject;
	}

	public HashMap<String, JSONObject> getDisplayFields() {
		return displayObects;
	}
}